Questions
2 of 11
1Evaluate this claim: 'Cosine similarity and normalized dot product always produce identical rankings.' What subtlety do candidates often miss here?
2Many candidates assume increasing ef at query time always improves recall with only a linear latency cost. What's misleading about that assumption?
3Why is 'just add more RAM' not always a valid answer to a Qdrant performance question in a system design interview?
4A candidate claims that quantization always speeds up search. Under what conditions might quantization with rescoring actually be slower than searching un-quantized vectors?
5Why can two identical-looking filter queries - one using an indexed field, one using an equivalent but unindexed field - have wildly different performance, even though they return the same results?
6At billion-point scale, how would your indexing and sharding strategy differ from a design that works fine at ten million points?
7How would you architect a system to gracefully degrade - rather than fail outright - when a burst of traffic exceeds provisioned Qdrant capacity?
8What are the limits of a purely payload-filter-based multitenancy model, and at what point would you need to introduce dedicated shards or collections per tenant instead?
9How would you approach re-embedding a multi-billion-point production collection with a new embedding model with zero search downtime?
10When designing a retrieval system that combines dense, sparse, and multivector reranking at extreme scale, what's the single biggest cost driver you'd optimize first, and why?
11If you were asked to design Qdrant's filtered-HNSW search from scratch, what core problem would you need to solve, and what naive approach would you reject first?
02 / 11

Many candidates assume increasing ef at query time always improves recall with only a linear latency cost. What's misleading about that assumption?

Recall saturates and latency grows non-linearly, especially with filters

The assumption has two parts, and both are misleading. The first part is that recall always improves with ef. In practice, recall vs ef is a concave curve that saturates: on most datasets, recall rises steeply from ef=16 to ef=128, then flattens, and beyond ef=256 the gain is often fractions of a point. The saturation point depends on the intrinsic dimensionality of the data and on how well the graph is built (m, ef_construct). Once the traversal has visited the entire relevant region of the graph, more ef does not find anything new. The second part is that latency grows linearly with ef. In a compute-bound regime, the number of distance computations does scale roughly linearly with ef, so latency grows roughly linearly. But in a memory-bound or cache-bound regime, higher ef means more nodes visited, which means more cache misses, which means latency grows faster than linearly. And when a filter is present, the picture changes: the filter-aware traversal has to explore more of the graph to find enough matching points, so the effective cost grows with the filter's selectivity. At very high ef with a selective filter, the traversal can approach a full scan, and the latency curve becomes steep.

The mechanism that produces the saturation is that HNSW is a greedy best-first search over a graph. The search terminates when the candidate list is exhausted - that is, when no unexplored neighbor is closer than the current worst result. Increasing ef makes the candidate list larger, which means the search explores more of the graph before terminating. But the graph has a finite number of nodes, and the relevant region for a query is bounded. Once the search has explored the entire connected region around the query, more ef only adds nodes that are farther away and do not change the top-k. This is why recall saturates. The mechanism that produces the non-linear latency is that higher ef visits more nodes, and each node visit has a cache cost. If the graph fits in cache, the cost per visit is low and latency grows roughly linearly. If the graph does not fit, each visit is more likely to miss the cache and pay a memory latency, so the cost per visit grows with the working set. The interaction with filters is that the filter reduces the fraction of visited nodes that are candidates, so the search must visit more nodes to find the same number of results, which amplifies both effects.

  1. 1

    Recall saturation: concave curve, steep up to ~ef=128, flat beyond ~ef=256.

  2. 2

    Saturation point: depends on intrinsic dimensionality and graph quality (m, ef_construct).

  3. 3

    Latency scaling: roughly linear in a compute-bound regime, worse in a cache-bound regime.

  4. 4

    Cache effects: higher ef visits more nodes, more cache misses, super-linear latency.

  5. 5

    Filter interaction: selective filters force more exploration, amplifying both effects.

  6. 6

    Diminishing returns: the marginal recall gain per unit of latency decreases as ef grows.

  7. 7

    Sensitivity: the knee of the curve is dataset-dependent; measure it on your own data.

  8. 8

    Alternative levers: raising m or ef_construct changes the curve itself, not the position on it.

The trade-off is between recall and latency, and the misconception is that the trade-off is uniform. It is not: the marginal cost of recall increases as you push toward high recall. This is why the right strategy is to find the knee of the curve and set the default ef there, then use higher ef only for specific queries that need it. The common mistakes are: (1) setting ef very high by default to maximize recall, which costs latency on every query for a small gain; (2) assuming the latency cost is linear and planning capacity accordingly, then discovering the tail is worse than expected; (3) ignoring the filter interaction, so filtered queries with high ef have much worse latency than unfiltered ones; (4) not measuring the recall-vs-ef curve on the actual data, so the knee is unknown; (5) treating ef as the only recall lever when m and ef_construct change the curve itself. Version note: the exact shape of the recall-vs-ef and latency-vs-ef curves depends on the Qdrant version's implementation of filter-aware traversal and on the storage layout (in-memory vs on-disk, quantized vs full precision). Re-measure after upgrades.

javascript

Version-dependent: the recall-vs-ef and latency-vs-ef curves depend on the Qdrant version's filter-aware traversal, the storage layout, and the quantization settings. Measure on your version and with your data rather than assuming a shape from a blog post.

Difficulty: 8/10
Topics: HNSW, Latency Tuning, Recall

Scenario Questions

0-2 years experience
  1. 1

    You set ef=1024 to maximize recall and latency is unacceptable. Explain what you would do instead.

  2. 2

    A teammate says ef always improves recall. Explain the saturation effect.

2-5 years experience
  1. 1

    Your recall improves only 0.3 points when you double ef from 128 to 256, but latency doubles. Describe how you would decide the default ef.

  2. 2

    A filtered query needs ef=512 to match the recall of an unfiltered query at ef=128. Diagnose the cause and propose fixes.

5-8 years experience
  1. 1

    Design an adaptive ef scheme that uses a low ef for easy queries and a high ef for hard ones. What signals would you use and how would you validate?

  2. 2

    You need to meet a recall SLO without exceeding a latency SLO. Describe the experiment and the decision.

8+ years experience
  1. 1

    Derive the relationship between ef, graph degree, and expected recall, and explain where the model predicts saturation.

  2. 2

    You are designing a system that must serve both high-recall and low-latency queries on the same collection. Describe the architecture and the trade-offs.

Follow-up Questions

  • How would you find the knee of the recall-vs-ef curve for a specific collection, and how would you decide the default ef from it?
  • If a filtered query needs a much higher ef than an unfiltered query to achieve the same recall, how would you detect and handle that?